wayland: Refactor the keymap handling so it is associated with device
authorJosé Dapena Paz <jdapena@igalia.com>
Mon, 16 Jul 2012 18:02:41 +0000 (19:02 +0100)
committerRob Bradford <rob@linux.intel.com>
Mon, 16 Jul 2012 19:11:41 +0000 (20:11 +0100)
Although GDK expects the keymap to be associated with the display under
Wayland this is really associated with the input device so expose this by
finding the first keyboard device.

Signed-off-by: Rob Bradford <rob@linux.intel.com>
gdk/wayland/gdkdevice-wayland.c
gdk/wayland/gdkdisplay-wayland.c
gdk/wayland/gdkkeys-wayland.c
gdk/wayland/gdkprivate-wayland.h

index 4054dc2cf6acbae89194845e7ffa1ec434bc2380..27b66731db8219688667efe03d3f3c6231b5410e 100644 (file)
@@ -65,6 +65,8 @@ struct _GdkWaylandDevice
   GdkDevice *pointer;
   GdkDevice *keyboard;
 
+  GdkKeymap *keymap;
+
   GdkModifierType modifiers;
   GdkWindow *pointer_focus;
   GdkWindow *keyboard_focus;
@@ -376,6 +378,12 @@ _gdk_wayland_device_get_wl_keyboard (GdkDevice *device)
   return GDK_DEVICE_CORE (device)->device->wl_keyboard;
 }
 
+GdkKeymap *
+_gdk_wayland_device_get_keymap (GdkDevice *device)
+{
+  return GDK_DEVICE_CORE (device)->device->keymap;
+}
+
 #if 0
 static void
 input_handle_motion(void *data, struct wl_input_device *input_device,
@@ -1157,36 +1165,10 @@ keyboard_handle_keymap (void               *data,
                        uint32_t            size)
 {
   GdkWaylandDevice *device = data;
-  GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
-  GdkKeymap *gdk_keymap;
-  gchar *keymap_data;
-  struct xkb_keymap *keymap;
-
-  if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
-    {
-      g_critical (G_STRLOC ": Unknown keymap format");
-      close (fd);
-      return;
-    }
-
-  keymap_data = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
-  if (keymap_data == MAP_FAILED)
-    {
-      g_critical (G_STRLOC ": Unable to map fd for keymap %s", g_strerror (errno));
-      close (fd);
-      return;
-    }
-
-  keymap = xkb_map_new_from_string (display->xkb_context,
-                                    keymap_data,
-                                    format,
-                                    0);
-
-  munmap (keymap_data, size);
-  close (fd);
+  if (device->keymap)
+    g_object_unref (device->keymap);
 
-  gdk_keymap = _gdk_wayland_display_get_keymap (device->display);
-  _gdk_wayland_keymap_update_keymap (gdk_keymap, keymap);
+  device->keymap = _gdk_wayland_keymap_new_from_fd (format, fd, size);
 }
 
 static void
@@ -1386,6 +1368,7 @@ _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager,
   display_wayland = GDK_WAYLAND_DISPLAY (display);
 
   device = g_new0 (GdkWaylandDevice, 1);
+  device->keymap = _gdk_wayland_keymap_new ();
   device->display = display;
   device->device_manager = device_manager;
 
index 84660a17ddadae7be44d88f56cdb74898fb00334..734fd10669496cbf4dc2b113fad7b962fbfb78fe 100644 (file)
@@ -536,15 +536,26 @@ gdk_wayland_display_event_data_free (GdkDisplay *display,
 GdkKeymap *
 _gdk_wayland_display_get_keymap (GdkDisplay *display)
 {
-  GdkWaylandDisplay *display_wayland;
+  GdkDeviceManager *device_manager;
+  GList *list, *l;
+  GdkDevice *core_keyboard = NULL;
 
-  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
-  display_wayland = GDK_WAYLAND_DISPLAY (display);
+  device_manager = gdk_display_get_device_manager (display);
+  list = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
 
-  if (!display_wayland->keymap)
-    display_wayland->keymap = _gdk_wayland_keymap_new (display);
+  for (l = list; l; l = l->next)
+    {
+      GdkDevice *device;
+      device = list->data;
+
+      if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
+       continue;
+
+      core_keyboard = device;
+      break;
+    }
 
-  return display_wayland->keymap;
+  return core_keyboard?_gdk_wayland_device_get_keymap (core_keyboard):NULL;
 }
 
 static void
index b4b205b6a2fbb2c3e79f3dc76b3a6872c5da298e..08b0b82c2e41b2936d0d8cc91efb8c85426773a8 100644 (file)
 #include <unistd.h>
 #include <limits.h>
 #include <errno.h>
+#include <sys/mman.h>
 
 #include "gdk.h"
 #include "gdkwayland.h"
 
 #include "gdkprivate-wayland.h"
 #include "gdkinternals.h"
-#include "gdkdisplay-wayland.h"
 #include "gdkkeysprivate.h"
 
 #include <xkbcommon/xkbcommon.h>
@@ -47,13 +47,8 @@ typedef struct _GdkWaylandKeymapClass     GdkWaylandKeymapClass;
 struct _GdkWaylandKeymap
 {
   GdkKeymap parent_instance;
-  GdkModifierType modmap[8];
-  struct xkb_desc *xkb;
-  struct xkb_keymap *keymap;
-  struct xkb_state *state;
-  xkb_mod_mask_t control_mask;
-  xkb_mod_mask_t alt_mask;
-  xkb_mod_mask_t shift_mask;
+
+  struct xkb_keymap *xkb_keymap;
 };
 
 struct _GdkWaylandKeymapClass
@@ -645,51 +640,56 @@ update_keymaps (GdkWaylandKeymap *keymap)
 #endif
 
 GdkKeymap *
-_gdk_wayland_keymap_new (GdkDisplay *display)
+_gdk_wayland_keymap_new ()
 {
   GdkWaylandKeymap *keymap;
+  struct xkb_context *context;
   struct xkb_rule_names names;
 
   keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL);
-  GDK_KEYMAP (keymap)->display = display;
-#if 0
+
+  context = xkb_context_new (0);
 
   names.rules = "evdev";
   names.model = "pc105";
   names.layout = "us";
   names.variant = "";
   names.options = "";
-  keymap->xkb = xkb_compile_keymap_from_rules(&names);
-  update_modmap (keymap);
-  update_keymaps (keymap);
-#endif
+  keymap->xkb_keymap = xkb_map_new_from_names(context, &names, XKB_MAP_COMPILE_PLACEHOLDER);
+  xkb_context_unref (context);
+
   return GDK_KEYMAP (keymap);
 }
 
-void
-_gdk_wayland_keymap_update_keymap (GdkKeymap  *gdk_keymap,
-                                   struct xkb_keymap *xkb_keymap)
+GdkKeymap *
+_gdk_wayland_keymap_new_from_fd (uint32_t format,
+                                 uint32_t fd, uint32_t size)
 {
   GdkWaylandKeymap *keymap;
+  struct xkb_context *context;
+  char *map_str;
 
-  keymap = GDK_WAYLAND_KEYMAP (gdk_keymap);
+  keymap = g_object_new (_gdk_wayland_keymap_get_type(), NULL);
 
-  if (keymap->keymap)
-    xkb_map_unref (keymap->keymap);
+  context = xkb_context_new (0);
 
-  keymap->keymap = xkb_keymap;
+  map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+  if (map_str == MAP_FAILED) {
+    close(fd);
+    return NULL;
+  }
 
-  if (keymap->state)
-    xkb_state_unref (keymap->state);
+  keymap->xkb_keymap = xkb_map_new_from_string (context, map_str, format, XKB_MAP_COMPILE_PLACEHOLDER);
+  munmap (map_str, size);
+  close (fd);
+  xkb_context_unref (context);
 
-  keymap->state = xkb_state_new (keymap->keymap);
+  return GDK_KEYMAP (keymap);
+}
 
-  keymap->control_mask =
-    1 << xkb_map_mod_get_index(keymap->keymap, "Control");
-  keymap->alt_mask =
-    1 << xkb_map_mod_get_index(keymap->keymap, "Mod1");
-  keymap->shift_mask =
-    1 << xkb_map_mod_get_index(keymap->keymap, "Shift");
+struct xkb_keymap *_gdk_wayland_keymap_get_xkb_keymap (GdkKeymap *keymap)
+{
+  return GDK_WAYLAND_KEYMAP (keymap)->xkb_keymap;
 }
 
 struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap)
index 607e99a1228f9afd98997daca5bb8ec59166b470..cfa9bd885ec065977076c2c4a5fa4c405592c366 100644 (file)
@@ -48,7 +48,9 @@ GType _gdk_wayland_window_get_type    (void);
 void _gdk_wayland_window_add_focus    (GdkWindow *window);
 void _gdk_wayland_window_remove_focus (GdkWindow *window);
 
-GdkKeymap *_gdk_wayland_keymap_new (GdkDisplay *display);
+GdkKeymap *_gdk_wayland_keymap_new (void);
+GdkKeymap *_gdk_wayland_keymap_new_from_fd (uint32_t format,
+                                            uint32_t fd, uint32_t size);
 struct xkb_desc *_gdk_wayland_keymap_get_xkb_desc (GdkKeymap *keymap);
 
 GdkCursor *_gdk_wayland_display_get_cursor_for_type (GdkDisplay    *display,
@@ -90,10 +92,6 @@ void _gdk_wayland_display_create_window_impl (GdkDisplay    *display,
                                              GdkWindowAttr *attributes,
                                              gint           attributes_mask);
 
-GdkKeymap *_gdk_wayland_display_get_keymap (GdkDisplay *display);
-void       _gdk_wayland_keymap_update_keymap (GdkKeymap  *gdk_keymap,
-                                              struct xkb_keymap *xkb_keymap);
-
 GdkWindow *_gdk_wayland_display_get_selection_owner (GdkDisplay *display,
                                                 GdkAtom     selection);
 gboolean   _gdk_wayland_display_set_selection_owner (GdkDisplay *display,
@@ -134,6 +132,8 @@ struct wl_seat *_gdk_wayland_device_get_wl_seat (GdkDevice *device);
 struct wl_pointer *_gdk_wayland_device_get_wl_pointer (GdkDevice *device);
 struct wl_keyboard *_gdk_wayland_device_get_wl_keyboard (GdkDevice *device);
 
+GdkKeymap *_gdk_wayland_device_get_keymap (GdkDevice *device);
+
 void     _gdk_wayland_display_deliver_event (GdkDisplay *display, GdkEvent *event);
 GSource *_gdk_wayland_display_event_source_new (GdkDisplay *display);
 void     _gdk_wayland_display_queue_events (GdkDisplay *display);